package com.cxd.performance.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.cxd.performance.domain.PerformanceBaseInfo;
import com.cxd.performance.domain.PerformanceScoreInfo;
import com.cxd.performance.service.impl.SendScoringMailServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class PerformanceScoreAnalysisEventListener extends AnalysisEventListener<PerformanceBaseInfo> {

    private static final String TEAM_ONE = "美创第一项目组";

    private static final String FILEPATH = "E:\\Elead\\绩效评分\\绩效评分汇总\\";


    List<PerformanceBaseInfo> baseInfoList = new ArrayList<>();

    @Override
    public void invoke(PerformanceBaseInfo performanceBaseInfo, AnalysisContext analysisContext) {
        baseInfoList.add(performanceBaseInfo);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //删除第一行表头
        baseInfoList.remove(0);
        //匹配规则
        List<PerformanceScoreInfo> performanceScoreInfosList = matchRulesCalculateScores(baseInfoList);
        //导出绩效评分
        exportPerformanceScore(performanceScoreInfosList);
    }

    private void exportPerformanceScore(List<PerformanceScoreInfo> performanceScoreInfosList) {
        Workbook wb = getTemplate("excel", "performanceScore.xlsx");
        Sheet sheet = wb.getSheetAt(0);
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        String targetFilePath = FILEPATH + "美创第一项目组" + "-" + year + "年" + month + "月-" + "绩效评分.xlsx";
        try (FileOutputStream output = new FileOutputStream(targetFilePath)) {
            int count = 1;
            for (PerformanceScoreInfo scoreInfo : performanceScoreInfosList) {
                Row row = sheet.getRow(count);
                if (row == null) {
                    row = sheet.createRow(count);
                }
                for (int j = 0; j <= 12; j++) {
                    Cell cell = row.getCell(j);
                    if (cell == null) {
                        row.createCell(j);
                    }
                }
                Cell cell0 = row.getCell(0);
                cell0.setCellValue(count);
                Cell cell1 = row.getCell(1);
                cell1.setCellValue("美创第一项目组");
                Cell cell2 = row.getCell(2);
                cell2.setCellValue(scoreInfo.getEmployeeName());
                Cell cell3 = row.getCell(3);
                cell3.setCellValue(50);
                Cell cell4 = row.getCell(4);
                cell4.setCellValue(30);
                Cell cell5 = row.getCell(5);
                if (null == scoreInfo.getAttendanceScore() || BigDecimal.ZERO.compareTo(scoreInfo.getAttendanceScore()) == 0) {
                    cell5.setCellValue(StringUtils.EMPTY);
                }else {
                    cell5.setCellValue(String.valueOf(scoreInfo.getAttendanceScore()));
                }
                Cell cell6 = row.getCell(6);
                if (null == scoreInfo.getWorkOvertimeScore() || 0 == scoreInfo.getWorkOvertimeScore()) {
                    cell6.setCellValue(StringUtils.EMPTY);
                }else {
                    cell6.setCellValue(scoreInfo.getWorkOvertimeScore());
                }
                Cell cell7 = row.getCell(7);
                if (null == scoreInfo.getRedBlackScore() || 0 == scoreInfo.getRedBlackScore()) {
                    cell7.setCellValue(StringUtils.EMPTY);
                }else {
                    cell7.setCellValue(scoreInfo.getRedBlackScore());
                }
                Cell cell8 = row.getCell(8);
                if (null == scoreInfo.getRecruitScore() || 0 == scoreInfo.getRecruitScore()) {
                    cell8.setCellValue(StringUtils.EMPTY);
                }else {
                    cell8.setCellValue(scoreInfo.getRecruitScore());
                }
                Cell cell9 = row.getCell(9);
                if (null == scoreInfo.getTutorScore() || 0 == scoreInfo.getTutorScore()) {
                    cell9.setCellValue(StringUtils.EMPTY);
                }else {
                    cell9.setCellValue(scoreInfo.getTutorScore());
                }
                Cell cell10 = row.getCell(10);
                if (null == scoreInfo.getShareScore() || 0 == scoreInfo.getShareScore()) {
                    cell10.setCellValue(StringUtils.EMPTY);
                }else {
                    cell10.setCellValue(scoreInfo.getShareScore());
                }
                Cell cell11 = row.getCell(11);
                if (null == scoreInfo.getDemandCreationScore() || 0 == scoreInfo.getDemandCreationScore()) {
                    cell11.setCellValue(StringUtils.EMPTY);
                }else {
                    cell11.setCellValue(scoreInfo.getDemandCreationScore());
                }
                Cell cell12 = row.getCell(12);
                if (null == scoreInfo.getTotalScore() || BigDecimal.ZERO.compareTo(scoreInfo.getTotalScore()) == 0) {
                    cell12.setCellValue(StringUtils.EMPTY);
                }else {
                    cell12.setCellValue(String.valueOf(scoreInfo.getTotalScore()));
                }
                count++;
            }
            Sheet sheet1 = wb.getSheetAt(1);
            Row row1 = sheet1.getRow(1);
            if (row1 == null) {
                row1 = sheet.createRow(1);
            }
            Cell cell2 = row1.getCell(2);
            if (cell2 == null) {
                row1.createCell(2);
            }
            assert cell2 != null;
            cell2.setCellValue(performanceScoreInfosList.size());
            Cell cell3 = row1.getCell(3);
            if (cell3 == null) {
                row1.createCell(3);
            }
            cell3.setCellValue(performanceScoreInfosList.size() * 35);
            //写入磁盘
            wb.write(output);
        } catch (Exception e) {
            log.error("导出excel出现异常", e);
        }
    }

    private List<PerformanceScoreInfo> matchRulesCalculateScores(List<PerformanceBaseInfo> baseInfoList) {
        baseInfoList = baseInfoList.stream().filter(x -> StringUtils.equalsIgnoreCase(TEAM_ONE, x.getTeam())).collect(Collectors.toList());
        List<PerformanceScoreInfo> scoreInfoList = new ArrayList<>();
        for (PerformanceBaseInfo performanceBaseInfo : baseInfoList) {
            PerformanceScoreInfo scoreInfo = new PerformanceScoreInfo();
            //考勤情况
            String diff = performanceBaseInfo.getDiff();
            BigDecimal diffValue = BigDecimal.ZERO;
            if (StringUtils.isNotBlank(diff)) {
                diffValue = calculateDeduction(new BigDecimal(diff).abs());
            }
            int latenessTimes = StringUtils.isNotBlank(performanceBaseInfo.getLatenessTimes()) ? Integer.parseInt(performanceBaseInfo.getLatenessTimes()) : 0;
            int missedClockTimes = StringUtils.isNotBlank(performanceBaseInfo.getMissedClockTimes()) ? Integer.parseInt(performanceBaseInfo.getMissedClockTimes()) : 0;
            int leaveOfAbsenceDay = StringUtils.isNotBlank(performanceBaseInfo.getLeaveOfAbsenceDay()) && Double.parseDouble(performanceBaseInfo.getLeaveOfAbsenceDay()) > 3 ? 5 : 0;
            BigDecimal totalAttendanceScore = (new BigDecimal(latenessTimes + missedClockTimes).multiply(new BigDecimal(1.5))).add(new BigDecimal(leaveOfAbsenceDay));
            scoreInfo.setAttendanceScore((totalAttendanceScore.add(diffValue).negate()));
            //加班时长
            int actualOvertimeNum = 0;
            if (StringUtils.isNotBlank(performanceBaseInfo.getActualOvertimeDay())) {
                double actualOvertimeDay = Double.parseDouble(performanceBaseInfo.getActualOvertimeDay());
                if (0 < actualOvertimeDay && actualOvertimeDay < 2.5) {
                    actualOvertimeNum = 1;
                }else if (actualOvertimeDay >= 2.5){
                    actualOvertimeNum = 2;
                }
            }
            scoreInfo.setWorkOvertimeScore(actualOvertimeNum * 5);
            //关键红黑事件
            //辅助招聘
            int internalRecommendation = StringUtils.isNotBlank(performanceBaseInfo.getInternalRecommendation()) ? 1 : 0;
            int interviewer = StringUtils.isNotBlank(performanceBaseInfo.getInterviewer()) ? 1 : 0;
            int totalRecruitScore = (internalRecommendation + interviewer) * 5;
            scoreInfo.setRecruitScore(totalRecruitScore);
            //讲师及团队分享
            int internalShare = StringUtils.isNotBlank(performanceBaseInfo.getInternalShare()) ? 1 : 0;
            scoreInfo.setShareScore(internalShare * 5);
            //需求挖掘
            int demandMining = StringUtils.isNotBlank(performanceBaseInfo.getDemandMining()) ? 1 : 0;
             scoreInfo.setDemandCreationScore(demandMining * 5);
            String employeeName = performanceBaseInfo.getEmployeeName();
            scoreInfo.setEmployeeName(employeeName);
            //月度得分
            BigDecimal totalScore = scoreInfo.getAttendanceScore().add(new BigDecimal(scoreInfo.getWorkOvertimeScore() + scoreInfo.getRecruitScore() + scoreInfo.getTutorScore()
                    + scoreInfo.getShareScore() + scoreInfo.getDemandCreationScore() + 80));
            scoreInfo.setTotalScore(totalScore);
            scoreInfoList.add(scoreInfo);
        }
        return scoreInfoList;
    }

    private Workbook getTemplate(String folder, String fileName) {
        ClassLoader loader = SendScoringMailServiceImpl.class.getClassLoader();
        String path = (new StringBuilder()).append(folder).append(File.separator)
                .append(fileName).toString();
        InputStream in = loader.getResourceAsStream(path);
        Workbook wb = null;
        boolean isE2007 = true;
        if (fileName.endsWith(".xls"))
            isE2007 = false;
        try {
            if (isE2007) {
                wb = new XSSFWorkbook(in);
            } else {
                wb = new HSSFWorkbook(in);
            }
        } catch (IOException e) {
            log.error("获取excel模板失败", e);
        }
        return wb;
    }

    /**
     * 计算超时扣分（使用BigDecimal保证精度）
     * @param hours 超时小时数
     * @return 总扣分数（BigDecimal类型）
     */
    public BigDecimal calculateDeduction(BigDecimal hours) {
        // 参数校验
        if (hours == null || hours.compareTo(BigDecimal.ZERO) < 0) {
            return BigDecimal.ZERO;
        }
        hours = hours.multiply(new BigDecimal(8)).setScale(0, RoundingMode.DOWN);;
        if (hours.compareTo(new BigDecimal(3)) < 0) {
            return BigDecimal.ZERO;
        }
        // 基础扣分：4小时扣3分
        BigDecimal baseDeduction = new BigDecimal("3.0");

        // 超出4小时的部分，每小时扣0.5分
        BigDecimal extraHours = hours.subtract(new BigDecimal("4.0")).max(BigDecimal.ZERO);
        BigDecimal extraDeduction = extraHours.multiply(new BigDecimal("0.5"));

        // 总扣分（四舍五入到整数）
        BigDecimal totalDeduction = baseDeduction.add(extraDeduction);

        // 扣分封顶10分
        return totalDeduction.min(new BigDecimal("10"));
    }

}
